home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DDJ0992.ARJ / SALTER.LS1 < prev    next >
INI File  |  1992-06-19  |  31KB  |  960 lines

  1. [LISTING ONE]
  2.  
  3. ; winx.asm - exception handler for windows 3.x
  4. .386p               ; 386 protect mode
  5. wincs equ 28h           ; windows ring 0 cs
  6. winds equ 30h           ; windows ring 0 ds
  7.     include psequate.inc    ; general Periscope equates
  8.     include dosmgr.inc  ; all of these
  9.     include shell.inc   ; are from the
  10.     include vdd.inc     ; windows ddk
  11.     include vmm.inc     ; ...
  12.     include vpicd.inc   ; ...
  13.     ; device descriptor block
  14. Declare_Virtual_Device WINX, 3, 0, VAD_Control, Undefined_Device_ID, 
  15.                                           VMM_Init_Order \ , , VAD_PM_Svc_Call
  16. ; ****************************************************************************
  17. VxD_Locked_Data_Seg     ; data segment
  18. datastart equ $         ; symbol for start of data
  19.     ; global data follows
  20. psport  dw 0            ; Periscope Model IV port number
  21. currow  db 0            ; cursor row (0-24)
  22. curcol  db 0            ; cursor column (0-79)
  23. showregs db 0           ; 1 when we have something to show
  24. usemono db 0            ; 1 when output to mono screen
  25. monosave db 0           ; 1 when saving mono screen
  26. winmsg  db 1            ; 1 when output to windows screen
  27.  
  28. even
  29. hextable db '0123456789ABCDEF'  ; hex conversion table
  30. even                ; gdt/idt/ldt data
  31. gdtlimit    dw 0        ; global descriptor table limit
  32. gdtbase     dd 0        ; and base
  33. idtlimit    dw 0        ; interrupt descriptor table limit
  34. idtbase     dd 0        ; and base
  35. ldtvalue    dw 0        ; value of local descriptor table
  36. ldtlimit    dw 0        ; and limit
  37. tssvalue    dw 0        ; value of task state selector
  38.         ; original interrupt values
  39. origint6    df 0        ; illegal opcode
  40. origint8    df 0        ; double fault
  41. originta    df 0        ; invalid tss
  42. origintb    df 0        ; segment not present
  43. origintc    df 0        ; stack fault
  44. origintd    df 0        ; general protection fault
  45. originte    df 0        ; page fault
  46. origirq1    df 0        ; original keyboard interrupt
  47. align 4
  48. jumptable   dd offset32 p206,offset32 origint6  ; control table
  49.         dd 0,0      ; dummy for interrupt 7
  50.         dd offset32 p208,offset32 origint8
  51.         dd 0,0      ; dummy for interrupt 9
  52.         dd offset32 p20a,offset32 originta
  53.         dd offset32 p20b,offset32 origintb
  54.         dd offset32 p20c,offset32 origintc
  55.         dd offset32 p20d,offset32 origintd
  56.         dd offset32 p20e,offset32 originte
  57. intlistlen  equ 9       ; number of interrupts in above list
  58. intlist     db '060708090a0b0c0d0e' ; list of 9 exception vecs
  59.     ; keep the following together
  60. hookint06   db 1        ; all but interrupts 7 and 9
  61. hookint07   db 0        ; get hooked by default
  62. hookint08   db 1
  63. hookint09   db 0
  64. hookint0a   db 1
  65. hookint0b   db 1
  66. hookint0c   db 1
  67. hookint0d   db 1
  68. hookint0e   db 1
  69.     ; end of keep together
  70. intgate     dw 0ee00h   ; value for interrupt gate, dpl=3
  71. keystrokes  dw 0        ; keystroke count
  72. errorcode   dd 0        ; error code on interrupts 8 and higher
  73. inttype     dw 0        ; interrupt type
  74. exitaddr    df 0        ; original interrupt address as 16:32 ptr
  75. align 4
  76.     ; original registers
  77. saveeax dd 0            ; original eax
  78. saveebx dd 0            ; original ebx
  79. saveecx dd 0            ; original ecx
  80. saveedx dd 0            ; original edx
  81. saveesp dd 0            ; original esp
  82. saveebp dd 0            ; original ebp
  83. saveesi dd 0            ; original esi
  84. saveedi dd 0            ; original edi
  85. saveeip dd 0            ; original eip
  86. saveefl dd 0            ; original eflags
  87. saveds  dw 0            ; original ds
  88. savees  dw 0            ; original es 
  89. savess  dw 0            ; original ss
  90. savecs  dw 0            ; original cs
  91. savefs  dw 0            ; original fs
  92. savegs  dw 0            ; original gs
  93.     ; instruction prefixes - these opcodes are ignored
  94.     ; when searching for the start of an instruction
  95. prelist db 026h,02eh,036h,03eh,064h,065h,066h,067h,0f0h,0f2h,0f3h
  96. prelistlen dd 11
  97.     ; legal opcodes for int b - pass these on thru to the original handler
  98. intblist db 0fh             ; improve later to catch only 
  99.                     ; 0f/b2, 0f/b4, 0f/b5
  100.     db 063h             ; arpl
  101.     db 09ah             ; far call
  102.     db 0c4h,0c5h            ; les/lds ... used by visual basic
  103.     db 0cah,0cbh            ; retf
  104.     db 0eah             ; far jmp
  105.     db 0f4h             ; hlt
  106.     db 0fah,0fbh            ; cli/sti
  107.     db 0ffh             ; various
  108. intblistlen dd 12
  109.     ; legal opcodes for int d - pass these on thru to the original handler
  110. intdlist  db 06ch,06dh,06eh,06fh    ; in/out
  111.     db 09ah             ; far call
  112.     db 09ch             ; pushf
  113.     db 09dh             ; popf
  114.     db 0cch,0cdh,0ceh       ; int x
  115.     db 0cfh             ; iret
  116.     db 0e4h,0e5h,0e6h,0e7h      ; in/out
  117.     db 0ech,0edh,0eeh,0efh      ; in/out
  118.     db 0f4h             ; hlt
  119.     db 0fah,0fbh            ; cli/sti
  120. intdlistlen dd 22
  121. even
  122. opcode db 8 dup(0)      ; save the opcode bytes here
  123. opcodecs dw 0           ; cs for opcodes
  124. opcodeeip dd 0          ; eip for opcodes
  125. explcount equ 7         ; number of interrupt descriptions
  126. expllen equ 20          ; length of each interrupt description
  127. explanations equ $      ; 1 byte for type, 20 bytes for text
  128. db 06h,'Invalid opcode      '
  129. db 08h,'Double fault        '
  130. db 0ah,'Invalid TSS         '
  131. db 0bh,'Segment not present '
  132. db 0ch,'Stack exception     '
  133. db 0dh,'General protection  '
  134. db 0eh,'Page fault          '
  135. modep   db 'Protect'        ; mode can be Protect or V86 only - we'll
  136. modev86 db 'V86    '        ; never seel Real mode here
  137.             ; start of display area
  138. regline1 db cr,lf,'Interrupt '
  139. xinttype db '..h - '
  140. xexplain db '....................'
  141.         db '  Mode='
  142. xmode   db '.......  Ring='
  143. xring   db '.'
  144.     db cr,lf
  145. regline2 db 'Error code='
  146. errorno db '0000 0000       Opcodes='
  147. xopcode db '.. .. .. .. .. .. .. ..'
  148.     db cr,lf
  149.     db cr,lf
  150. regline3 db 'eax='
  151. regeax  db '.... ....  '
  152.     db 'ebx='
  153. regebx  db '.... ....  '
  154.     db 'ecx='
  155. regecx  db '.... ....  '
  156.     db 'edx='
  157. regedx  db '.... ....'
  158.     db cr,lf
  159. regline4 db 'ebp='
  160. regebp  db '.... ....  '
  161.     db 'efl='
  162. regefl  db '.... ....  '
  163.     db ' fs='
  164. regfs   db '....       '
  165.     db ' gs='
  166. reggs   db '....'
  167.     db cr,lf
  168. regline5 db 'eip='
  169. regeip  db '.... ....  '
  170.         db 'esp='
  171. regesp  db '.... ....  '
  172.     db 'esi='
  173. regesi  db '.... ....  '
  174.     db 'edi='
  175. regedi  db '.... ....'
  176.     db cr,lf
  177. regline6 db ' cs='
  178. regcs   db '....       '
  179.         db ' ss='
  180. regss   db '....       '
  181.     db ' ds='
  182. regds   db '....       '
  183.     db ' es='
  184. reges   db '....'
  185.     db cr,lf
  186.     db cr,lf
  187. regline7 db 'cr0=' 
  188. regcr0  db '.... ....  '
  189.     db 'cr2='
  190. regcr2  db '.... ....  '
  191.     db 'cr3='
  192. regcr3  db '.... ....'
  193.     db cr,lf
  194. regline8 db 'gdt='
  195. gdtb db '.... ..../'
  196. gdtl db '....  '
  197.     db 'ldt='
  198. ldtw    db '....  '
  199.     db 'idt='
  200. idtb db '.... ..../'
  201. idtl db '....  '
  202.     db 'tss='
  203. tssw    db '....'
  204.     db cr,lf
  205. regend  db 0,'$'
  206.                 ; end of display area
  207.     ; messages
  208. pause   db 'Press a key to continue ...',0
  209. crlf    db cr,lf,0
  210. periscopeid db 'WINX (Windows Exception Handler)'
  211.     db 0
  212. align 4 
  213. monoscreen dw 80*25 dup(0)  ; save the mono screen here
  214. VxD_Locked_Data_Ends        ; end of data segment
  215. ; ****************************************************************************
  216. VxD_Locked_Code_Seg     ; code segment
  217. codestart equ $         ; symbol for start of code
  218.     ; device control procedure 
  219. VAD_Control proc near       ; control table
  220.     Control_Dispatch Sys_Critical_Init, VAD_Sys_Crit_Init ; phase 1
  221.     Control_Dispatch Device_Init,       VAD_Device_Init   ; phase 2
  222.     Control_Dispatch Init_Complete,     VAD_Init_Complete ; phase 3
  223.     Control_Dispatch Create_VM,     VAD_Create_VM
  224.     clc         ; no errors
  225.     ret
  226. VAD_Control endp
  227. beginproc VAD_Get_Version, SERVICE
  228.     mov eax,300h
  229.     clc         ; no errors
  230.     ret
  231. endproc VAD_Get_Version
  232. VAD_PM_Svc_Call proc near
  233.     ret
  234. VAD_PM_Svc_Call endp
  235. align 4
  236. p006    proc near       ; int 6 handler
  237.     push eax
  238.     mov al,6
  239.     jmp short p020      ; to handler
  240. p006    endp
  241. align 4
  242. p008    proc near       ; int 8 handler
  243.     push eax
  244.     mov al,8
  245.     jmp short p020      ; to handler
  246. p008    endp
  247. align 4
  248. p00a    proc near       ; int a handler
  249.     push eax
  250.     mov al,0ah
  251.     jmp short p020      ; to handler
  252. p00a    endp
  253. align 4
  254. p00b    proc near       ; int b handler
  255.     push eax
  256.     mov al,0bh
  257.     jmp short p020      ; to handler
  258. p00b    endp
  259. align 4
  260. p00c    proc near       ; int c handler
  261.     push eax
  262.     mov al,0ch
  263.     jmp short p020      ; to handler
  264. p00c    endp
  265. align 4
  266. p00d    proc near       ; int d handler
  267.     push eax
  268.     mov al,0dh
  269.     jmp short p020      ; to handler
  270. p00d    endp
  271. align 4
  272. p00e    proc near       ; int e handler
  273.     push eax
  274.     mov al,0eh
  275.     jmp short p020      ; to handler
  276. p00e    endp
  277. align 4
  278. p013    proc near       ; irq 1 handler
  279.     ; this routine hooks the keyboard; it is used only to count
  280.     ; the number of keystrokes coming through
  281.     @save eax,ds        
  282.     mov ax,winds
  283.     mov ds,ax
  284.     inc keystrokes      ; count keystrokes
  285.     @restore
  286.     jmp cs:[origirq1]   ; pass control onto prior handler
  287. p013    endp
  288. align 4
  289. p020    proc near       ; exception handler
  290.     ; this is the common entry point for all exception handlers
  291.     push ds         ; save registers
  292.     push es
  293.     push ebp
  294.     cld         ; up!
  295.     push eax
  296.     mov ax,winds
  297.     mov ds,ax       ; set ds to windows ring 0 ds
  298.     pop eax
  299.     mov ah,0
  300.     mov inttype,ax      ; save interrupt type
  301.     mov ebp,esp     ; save registers
  302.     mov eax,[ebp]       ; 0=ebp,4=es,8=ds,12=eax,16=error/eip
  303.     mov saveebp,eax     ; save ebp
  304.     mov ax,[ebp+4]      ; get es from stack
  305.     mov savees,ax       ; save es
  306.     mov ax,[ebp+8]      ; get ds from stack
  307.     mov saveds,ax       ; save ds
  308.     mov eax,[ebp+12]    ; get eax from stack
  309.     mov saveeax,eax     ; save eax
  310.     mov saveebx,ebx     ; save ebx
  311.     mov saveecx,ecx     ; save ecx
  312.     mov saveedx,edx     ; save edx
  313.     mov saveesi,esi     ; save esi
  314.     mov saveedi,edi     ; save edi
  315.     mov savefs,fs       ; save fs
  316.     mov savegs,gs       ; save gs
  317.     mov ebp,esp
  318.     add ebp,16      ; point to eip/error
  319.     mov errorcode,0     ; clear error code
  320.     cmp inttype,8       ; error code?
  321.     jb short p020a      ; no
  322.     mov eax,[ebp]       ; get error code
  323.     mov errorcode,eax   ; save error code
  324.     add ebp,4       
  325. p020a:  mov eax,[ebp]       ; get eip from stack
  326.     mov saveeip,eax     ; save eip
  327.     mov ax,[ebp+4]      ; get cs from stack
  328.     mov savecs,ax       ; save cs
  329.     mov eax,[ebp+8]     ; get flags from stack
  330.     mov saveefl,eax     ; save flags
  331.     mov savess,ss
  332.     mov eax,ebp     ; get sp
  333.     add eax,12      ; skip eip, cs, & flags
  334.     mov saveesp,eax     ; save esp
  335.     test saveefl,bit17on    ; v86 mode?
  336.     jnz short p020d     ; yes
  337.     test savecs,3       ; ring 0 cs?
  338.     jz short p020b      ; yes
  339. p020d:
  340.     mov eax,[ebp+12]    ; get esp from stack
  341.     mov saveesp,eax     ; save esp
  342.     mov ax,[ebp+16]     ; get ss from stack
  343.     mov savess,ax       ; save ss
  344.     test saveefl,bit17on    ; v86 mode?
  345.     jz short p020b      ; no
  346.     mov ax,[ebp+20]     ; get es from stack
  347.     mov savees,ax       ; save es
  348.     mov ax,[ebp+24]     ; get ds from stack
  349.     mov saveds,ax       ; save ds
  350.     mov ax,[ebp+28]     ; get fs from stack
  351.     mov savefs,ax       ; save fs
  352.     mov ax,[ebp+32]     ; get gs from stack
  353.     mov savegs,ax       ; save gs
  354. p020b:  pushad          ; a bit redundant, but it's small
  355.     call p200       ; check exceptions
  356.     jnc short p020x     ; ok - skip display
  357.     mov dx,psport       ; get Periscope port
  358.     cmp dx,0        ; valid?
  359.     jz short p020c      ; no
  360.     mov al,0dbh
  361.     out dx,al       ; stop Periscope Model IV trace
  362. p020c:  call p950       ; display registers
  363.     mov showregs,1      ; indicate we have something to show
  364. p020x:  popad           ; pop all registers
  365.     pop ebp
  366.     pop es
  367.     pop ds
  368.     pop eax
  369.     jmp fword ptr cs:[exitaddr] ; pass control on to original handler
  370. p020    endp
  371. align 4
  372. p200    proc near       ; check exceptions
  373.     mov ax,ds
  374.     mov es,ax       ; es=ds
  375.     movzx eax,inttype   ; get interrupt type
  376.     sub eax,6       ; table starts at int 6
  377.     shl eax,3       ; times 8
  378.     mov esi,[jumptable+eax+4]
  379.     mov edi,offset32 exitaddr
  380.     movsw
  381.     movsd           ; copy original int to exitaddr
  382.     jmp [jumptable+eax]     ; handle the interrupt
  383. p200    endp
  384. align 4
  385. p206    proc near       ; handle int 6 - illegal instruction
  386.     call p220       ; get opcode in al
  387.     cmp al,63h      ; arpl instruction? (ms patented technique!)
  388.     jz short p206n      ; yes - don't show registers 
  389.     mov ax,word ptr opcode
  390.     cmp ax,0ff0fh       ; 0f ff opcode? (ms special case)
  391.     jz short p206n      ; yes - don't show registers 
  392.     stc         ; show registers
  393.     ret
  394. p206n:  clc         ; don't show registers
  395.     ret
  396. p206    endp
  397. align 4
  398. p208    proc near       ; handle int 8 - double fault
  399.     stc         ; show registers on all int 8
  400.     ret
  401. p208    endp
  402. align 4
  403. p20a    proc near       ; handle int a - invalid tss
  404.     stc         ; show registers on all int a
  405.     ret
  406. p20a    endp
  407. align 4
  408. p20b    proc near       ; handle int b - segment not present
  409.     test saveefl,bit17on    ; v86 mode?
  410.     jnz short p20bs     ; yes - show registers
  411.     call p220       ; get opcode in al
  412.     mov edi,offset32 intblist
  413.     mov ecx,intblistlen
  414.     repnz scasb     ; search for opcode
  415.     jnz short p20bs     ; no match
  416. p20bn:  clc         ; don't show registers
  417.     ret
  418. p20bs:  stc         ; show registers
  419.     ret
  420. p20b    endp
  421. align 4
  422. p20c    proc near       ; handle int c - stack fault
  423.     stc         ; show registers on all int c
  424.     ret
  425. p20c    endp
  426. align 4
  427. p20d    proc near       ; handle int d - general protection fault
  428.     call p220       ; get opcode in al
  429.     mov edi,offset32 intdlist
  430.     mov ecx,intdlistlen
  431.     cmp al,0cdh     ; get an int?
  432.     jz short p20dc      ; yes
  433.     repnz scasb     ; search for opcode
  434.     jnz short p20ds     ; no match
  435. p20dn:  clc         ; don't show registers
  436.     ret
  437. p20ds:  stc         ; show registers
  438.     ret
  439. p20dc:  ; expand to handle individual interrupts as needed
  440.     jmp p20dn
  441. p20d    endp
  442. align 4
  443. p20e    proc near       ; handle int e - page fault
  444.     clc         ; don't show registers
  445.     ret 
  446. p20e    endp
  447. align 4
  448. p220    proc near       ; get opcode byte in register al
  449.     test saveefl,bit17on    ; v86 mode?
  450.     jz short p220a      ; no
  451.     movzx ebx,savecs    ; get opcode address for v86 mode
  452.     shl ebx,4       ; times 16
  453.     add ebx,saveeip     ; plus eip
  454.     mov opcodecs,ds     ; use flat selector
  455.     mov opcodeeip,ebx   ; and our derived offset
  456.     jmp short p220b 
  457. p220a:  
  458.     mov bx,savecs       ; get opcode address for protect mode
  459.     mov opcodecs,bx     ; save cs
  460.     mov ebx,saveeip
  461.     mov opcodeeip,ebx   ; and eip
  462. p220b:  mov edi,offset32 opcode
  463.     mov ax,ds
  464.     mov es,ax       ; es=ds
  465.     mov ecx,8
  466.     mov esi,opcodeeip
  467.     push ds
  468.     mov ds,opcodecs
  469.     rep movsb       ; copy opcodes from user's cs:eip to us
  470.     pop ds
  471. mov esi,offset32 opcode
  472. p220c:  lodsb           ; get opcode byte
  473.     cmp esi,offset32 opcode+8   ; too far?
  474.     jae short p220d     ; yes - bail out
  475.     mov edi,offset32 prelist    ; is it a prefix byte?
  476.     mov ecx,prelistlen
  477.     repnz scasb     ; search for prefix
  478.     jz p220c        ; got a prefix - get next byte
  479. p220d:  ret
  480. p220    endp
  481. align 4
  482. p300    proc near       ; display message using Windows services
  483.     ; this routine is used as a callback unless WinxNoWinMsg is used
  484.     cmp showregs,1      ; something to show?
  485.     jz short p300a      ; yes
  486.     ret         ; no - exit now
  487. p300a:  @save eax,ebx,ecx,esi,edi   ; save registers
  488.     VMMcall Get_Cur_VM_Handle   ; get handle in ebx
  489.     mov eax,mb_iconhand+mb_ok
  490.     mov ecx,offset32 regline1
  491.     xor esi,esi     ; no callback
  492.     mov edi,offset32 periscopeid
  493.     VxDcall Shell_Sysmodal_Message  ; display message
  494.     mov showregs,0      ; nothing to show for now
  495.     @restore
  496.     ret
  497. p300    endp
  498. align 4
  499. p880    proc near       ; convert byte in al and output it to [edi]
  500.     push ebx
  501.     mov ah,0
  502.     mov ebx,offset32 hextable
  503.     shl ax,4        ; high nibble in ah
  504.     shr al,4        ; low nibble in al
  505.     xlat            ; convert low nibble
  506.     xchg ah,al
  507.     xlat            ; convert high nibble
  508.     mov [edi],ax        ; save the result
  509.     inc edi
  510.     inc edi         ; point to next output address
  511.     pop ebx
  512.     ret
  513. p880    endp
  514. align 4
  515. p885    proc near       ; convert word in dx and output it to [edi]
  516.     push eax
  517.     mov al,dh
  518.     call p880       ; convert high byte
  519.     mov al,dl
  520.     call p880       ; convert low byte
  521.     pop eax
  522.     ret
  523. p885    endp
  524. align 4
  525. p889    proc near       ; convert dword in edx and output it to [edi]
  526.     rol edx,16
  527.     call p885       ; convert high word
  528.     inc edi         ; a space between the high and low words
  529.     rol edx,16
  530.     call p885       ; convert low word
  531.     inc edi         ; a space after the low word
  532.     ret
  533. p889    endp
  534. align 4
  535. p900    proc near       ; display string on mono screen
  536.     @save eax,esi,edi,es
  537.     ; entry: esi points to string
  538.     mov ax,ds
  539.     mov es,ax       ; es=ds
  540. p900d:  call p905       ; calc offset
  541. p900a:  lodsb           ; get next byte
  542.     cmp al,0        ; end?
  543.     jz short p900x      ; yes
  544.     cmp al,cr       ; cr?
  545.     jz short p900b      ; yes
  546.     cmp al,lf       ; lf?
  547.     jz short p900c      ; yes
  548.     mov ah,0fh      ; high intensity
  549.     stosw           ; output it
  550.     inc curcol      ; bump column number
  551.     cmp curcol,79       ; at end of screen?
  552.     jbe p900a       ; no
  553.     mov curcol,0        ; line overflow
  554.     jmp short p900c     ; force an lf
  555. p900b:              ; handle cr
  556.     mov curcol,0        ; column 0
  557.     jmp short p900d     ; force recalc
  558. p900c:              ; handle lf
  559.     inc currow      ; next row
  560.     cmp currow,25       ; on row 25?
  561.     jb short p900d      ; no - force recalc
  562.     call p915       ; scroll the screen
  563.     jmp short p900d     ; recalc now
  564. p900x:  @restore
  565.     ret
  566. p900    endp
  567. align 4
  568. p905    proc near       ; calc offset in di using currow, curcol
  569.     @save eax,ebx,ecx
  570.     movzx eax,currow    ; current row
  571.     mov cl,80*2
  572.     mul cl          ; times 160 
  573.     movzx ebx,curcol
  574.     shl ebx,1       ; plus (column times 2)
  575.     add eax,ebx     ; gives offset relative to mono screen
  576.     add eax,0b0000h     ; plus mono segment*16 gives 32-bit offset
  577.     mov edi,eax     ; return result in edi
  578.     @restore
  579.     ret
  580. p905    endp
  581. align 4
  582. p910    proc near       ; clear mono screen
  583.     @save eax,ecx,edi,es
  584.     mov ax,ds
  585.     mov es,ax       ; es=ds
  586.     mov ax,720h
  587.     mov edi,0b0000h
  588.     mov ecx,25*80
  589.     rep stosw       ; init the screen
  590.     mov currow,cl       ; set these to zero
  591.     mov curcol,cl
  592.     @restore
  593.     ret
  594. p910    endp
  595. align 4
  596. p915    proc near       ; scroll mono screen
  597.     @save eax,ecx,esi,edi,es
  598.     mov ax,ds
  599.     mov es,ax       ; es=ds
  600.     mov esi,0b0000h
  601.     mov edi,esi
  602.     add esi,80*2        ; skip a line
  603.     mov ecx,24*80/2     ; dwords to copy
  604.     rep movsd       ; scroll it
  605.     mov ax,0720h
  606.     mov ecx,80/2        ; dwords in a line
  607.     rep stosd       ; blank last line
  608.     mov currow,24       ; now at row 24
  609.     mov curcol,cl       ; colum 0
  610.     @restore
  611.     ret
  612. p915    endp
  613. align 4
  614. p950    proc near       ; display registers
  615.     mov ax,inttype
  616.     mov edi,offset32 xinttype
  617.     call p880       ; convert byte
  618.     mov ax,inttype
  619.     mov ah,al       ; int type in ah
  620.     mov esi,offset32 explanations   ; point to interrupt descriptions
  621.     mov ecx,explcount   ; number of descriptions
  622. p950b:  lodsb           ; get the byte
  623.     cmp al,ah       ; does it match?
  624.     jz short p950c      ; yes
  625.     add esi,expllen     ; add the message length
  626.     loop p950b      ; and try again
  627.     jmp short p950d     ; no find
  628. p950c:  mov edi,offset32 xexplain ; point to output buffer
  629.     mov ecx,expllen     ; length of message
  630.     rep movsb       ; copy it across
  631. p950d:
  632.     mov ax,savecs
  633.     and eax,3       ; isolate cs ring bits
  634.     add al,'0'      ; convert to ascii
  635.     mov xring,al        ; save it
  636.     mov esi,offset32 modep  ; assume protect mode
  637.     test saveefl,bit17on    ; v86 mode?
  638.     jz short p950e      ; no
  639.     mov esi,offset32 modev86
  640.     mov xring,'3'       ; v86 is always ring 3
  641. p950e:  mov edi,offset32 xmode  ; point to output buffer
  642.     mov ecx,7
  643.     rep movsb       ; copy mode across
  644.     mov edx,errorcode
  645.     mov edi,offset32 errorno
  646.     call p889       ; convert error code
  647.     mov ecx,8 
  648.     mov esi,offset32 opcode ; point to opcode bytes
  649.     mov edi,offset32 xopcode
  650. p950a:  lodsb           ; get byte
  651.     call p880       ; convert byte
  652.     inc edi
  653.     loop p950a      ; continue
  654.     mov edx,saveeax 
  655.     mov edi,offset32 regeax
  656.     call p889       ; convert eax
  657.     mov edx,saveebx 
  658.     mov edi,offset32 regebx
  659.     call p889       ; convert ebx
  660.     mov edx,saveecx 
  661.     mov edi,offset32 regecx
  662.     call p889       ; convert ecx
  663.     mov edx,saveedx 
  664.     mov edi,offset32 regedx
  665.     call p889       ; convert edx
  666.     mov edx,saveebp 
  667.     mov edi,offset32 regebp
  668.     call p889       ; convert ebp
  669.     mov edx,saveesp 
  670.     mov edi,offset32 regesp
  671.     call p889       ; convert esp
  672.     mov edx,saveesi 
  673.     mov edi,offset32 regesi
  674.     call p889       ; convert esi
  675.     mov edx,saveedi 
  676.     mov edi,offset32 regedi
  677.     call p889       ; convert edi
  678.     mov edx,saveeip
  679.     mov edi,offset32 regeip
  680.     call p889       ; convert eip
  681.     mov edx,saveefl  
  682.     mov edi,offset32 regefl
  683.     call p889       ; convert efl
  684.     mov dx,savecs
  685.     mov edi,offset32 regcs
  686.     call p885       ; convert cs
  687.     mov dx,saveds
  688.     mov edi,offset32 regds
  689.     call p885       ; convert ds
  690.     mov dx,savees
  691.     mov edi,offset32 reges
  692.     call p885       ; convert es
  693.     mov dx,savefs
  694.     mov edi,offset32 regfs
  695.     call p885       ; convert fs
  696.     mov dx,savegs
  697.     mov edi,offset32 reggs
  698.     call p885       ; convert gs
  699.     mov dx,savess
  700.     mov edi,offset32 regss
  701.     call p885       ; convert ss
  702.     mov edx,cr0
  703.     mov edi,offset32 regcr0
  704.     call p889       ; convert cr0
  705.     mov edx,cr2
  706.     mov edi,offset32 regcr2
  707.     call p889       ; convert cr2
  708.     mov edx,cr3
  709.     mov edi,offset32 regcr3
  710.     call p889       ; convert cr3
  711.     sidt fword ptr idtlimit
  712.     mov edx,idtbase     ; get idt base
  713.     mov edi,offset32 idtb
  714.     call p889       ; convert idt base
  715.     mov dx,idtlimit     ; get idt limit
  716.     mov edi,offset32 idtl  
  717.     call p885       ; convert idt limit
  718.     sgdt fword ptr gdtlimit
  719.     mov edx,gdtbase     ; get gdt base
  720.     mov edi,offset32 gdtb
  721.     call p889       ; convert gdt base
  722.     mov dx,gdtlimit     ; get gdt limit
  723.     mov edi,offset32 gdtl
  724.     call p885       ; convert gdt limit
  725.     sldt ldtvalue
  726.     mov dx,ldtvalue     ; get ldt 
  727.     mov edi,offset32 ldtw
  728.     call p885       ; convert ldt
  729.     str tssvalue
  730.     mov dx,tssvalue     ; get tss 
  731.     mov edi,offset32 tssw
  732.     call p885       ; convert tss
  733.     cmp usemono,0       ; use mono screen?
  734.     jz short p950x      ; no
  735.     call p960       ; save/clear mono screen if needed
  736.     mov esi,offset32 regline1
  737.     call p900       ; display registers
  738.     mov esi,offset32 pause
  739.     call p900       ; display pause msg
  740.     mov keystrokes,0    ; clear keystrokes
  741.     sti         ; allow interrupts
  742. p950l:  cmp keystrokes,2    ; get 2 irq1s yet?
  743.     jb p950l        ; no
  744.     mov esi,offset32 crlf
  745.     call p900       ; display a crlf
  746.     call p970       ; restore mono screen if needed
  747.     cli         ; no more interrupts for now
  748. p950x:  ret
  749. p950    endp
  750. align 4
  751. p960    proc near       ; save/clear mono screen
  752.     cmp monosave,1      ; save it?
  753.     jnz short p960x     ; no
  754.     mov ax,ds
  755.     mov es,ax       ; es=ds
  756.     mov esi,0b0000h
  757.     mov edi,offset32 monoscreen
  758.     mov ecx,80*25/2
  759.     rep movsd       ; save the screen
  760.     call p910       ; clear the screen
  761. p960x:  ret
  762. p960    endp
  763. align 4
  764. p970    proc near       ; restore mono screen
  765.     cmp monosave,1      ; save it?
  766.     jnz short p970x     ; no
  767.     mov ax,ds
  768.     mov es,ax       ; es=ds
  769.     mov esi,offset32 monoscreen
  770.     mov edi,0b0000h
  771.     mov ecx,80*25/2
  772.     rep movsd       ; restore the screen
  773. p970x:  ret
  774. p970    endp
  775. VAD_Create_VM proc near
  776.     ret
  777. VAD_Create_VM endp
  778. VxD_Locked_Code_Ends
  779. ; ****************************************************************************
  780. VxD_Real_Init_Seg       ; init seg (real mode)
  781. p1000   proc near
  782.     mov ah,9
  783.     mov dx,offset copyr  
  784.     int 21h         ; display copyright
  785.     xor ax,ax       ; don't abort load
  786.     xor bx,bx       ; don't exclude any pages
  787.     xor si,si       ; no instance data items
  788.     xor edx,edx     ; dword of reference data
  789.     ret
  790. p1000   endp
  791. copyr   db 'WINX (Windows Exception Handler) Version 0.88'
  792.     db cr,lf
  793.     db 'Copyright 1991, The Periscope Company, Inc.  All rights reserved.'
  794.     db cr,lf,'$'
  795. VxD_Real_Init_Ends      ; init seg (real mode)
  796. ; ****************************************************************************
  797. VxD_Idata_Seg           ; init data seg (protect mode)
  798. winxusemono db 'WinxUseMono',0  ; tokens in system.ini
  799. winxmonosave    db 'WinxMonoSave',0
  800. winxnowinmsg    db 'WinxNoWinMsg',0
  801. winxpsport  db 'PeriscopePort',0
  802. winxnoint   db 'WinxNoInt'
  803. winxnoint2  db '..',0
  804. VxD_Idata_Ends
  805. ; ****************************************************************************
  806. VxD_Icode_Seg           ; init code seg (protect mode)
  807. VAD_Sys_Crit_Init proc near ; init phase 1
  808.     xor edx,edx     ; pointer to default string
  809.     xor esi,esi     ; look in [386enh]
  810.     mov edi,offset32 WinxUseMono
  811.     VMMcall Get_Profile_String  ; search for 'WinxUseMono'
  812.     jc short p1100a     ; no find 
  813.     mov usemono,1       ; use mono screen
  814.     call p1120      ; init mono screen
  815. p1100a:
  816.     xor edx,edx     ; pointer to default string
  817.     xor esi,esi     ; look in [386enh]
  818.     mov edi,offset32 WinxNoWinMsg
  819.     VMMcall Get_Profile_String  ; search for 'WinxNoWinMsg'
  820.     jc short p1100b     ; no find 
  821.     mov winmsg,0        ; no windows messages
  822. p1100b:
  823.     xor eax,eax     ; zap value
  824.     xor esi,esi     ; look in [386enh]
  825.     mov edi,offset32 WinxPSPort
  826.     VMMcall Get_Profile_Hex_Int ; search for 'PeriscopePort'
  827.     jc short p1100c     ; no find 
  828.     mov psport,ax       ; set Periscope's port
  829. p1100c:
  830.     xor edx,edx     ; pointer to default string
  831.     xor esi,esi     ; look in [386enh]
  832.     mov edi,offset32 WinxMonoSave
  833.     VMMcall Get_Profile_String  ; search for 'WinxMonoSave'
  834.     jc short p1100d     ; no find 
  835.     mov monosave,1      ; save/restore mono screen
  836.     call p1120      ; init mono screen
  837. p1100d:
  838.     mov eax,offset32 hookint06
  839.     mov ebx,offset32 intlist
  840.     mov ecx,intlistlen  ; count of interrupts
  841. p1100e: xor edx,edx     ; pointer to default string
  842.     xor esi,esi     ; look in [386enh]
  843.     mov edi,offset32 winxnoint
  844.     push ebx
  845.     mov bx,[ebx]        ; get int name in ascii
  846.     mov word ptr [winxnoint2],bx    ; save it
  847.     VMMcall Get_Profile_String  ; search for 'WinxNoInt..'
  848.     jc short p1100f     ; no find 
  849.     mov byte ptr [eax],0    ; don't hook this int
  850. p1100f: pop ebx
  851.     inc ebx
  852.     inc ebx
  853.     inc eax
  854.     loop p1100e     ; check all of our interrupts
  855.     call p1140      ; hook the indicated interrupts
  856.     clc         ; no error
  857.     ret
  858. align 4
  859. p1120   proc near       ; init mono screen
  860.     mov ax,ds
  861.     mov es,ax       ; es=ds
  862.     mov edi,0b0000h     ; init mono screen
  863.     mov ax,0720h
  864.     mov ecx,25*80
  865.     rep stosw
  866.     ret
  867. p1120   endp
  868. align 4
  869. p1140   proc near       ; set interrupts in idt
  870.     mov intgate,0ee00h  ; set interrupt gate, dpl=3
  871.     mov eax,offset32 p006   ; offset of exception handler
  872.     mov ebx,offset32 origint6   ; offset of original cs:eip
  873.     mov cl,hookint06    ; if 1, we hook this interrupt
  874.     mov edi,int6*2      ; offset of interrupt in idt
  875.     call p1160      ; set int 6
  876.     mov eax,offset32 p008
  877.     mov ebx,offset32 origint8
  878.     mov cl,hookint08
  879.     mov edi,int8*2
  880.     call p1160      ; set int 8
  881.     mov eax,offset32 p00a
  882.     mov ebx,offset32 originta
  883.     mov cl,hookint0a
  884.     mov edi,int0a*2
  885.     call p1160      ; set int a
  886.     mov eax,offset32 p00b
  887.     mov ebx,offset32 origintb
  888.     mov cl,hookint0b
  889.     mov edi,int0b*2
  890.     call p1160      ; set int b
  891.     mov eax,offset32 p00c
  892.     mov ebx,offset32 origintc
  893.     mov cl,hookint0c
  894.     mov edi,int0c*2
  895.     call p1160      ; set int c
  896.     mov eax,offset32 p00d
  897.     mov ebx,offset32 origintd
  898.     mov cl,hookint0d
  899.     mov edi,int0d*2
  900.     call p1160      ; set int d
  901.     mov eax,offset32 p00e
  902.     mov ebx,offset32 originte
  903.     mov cl,hookint0e
  904.     mov edi,int0e*2
  905.     call p1160      ; set int e
  906.     mov intgate,08e00h  ; interrupt gate, dpl=0
  907.     mov eax,offset32 p013
  908.     mov ebx,offset32 origirq1 
  909.     mov cl,1        ; always hook this interrupt
  910.     mov edi,51h*8
  911.     call p1160      ; set int 51h (keyboard)
  912.     ret
  913. p1140   endp
  914. p1160   proc near       ; set interrupt in idt
  915.     ; on entry, eax has offset of new handler,
  916.     ; ebx points to save area for current handler's address,
  917.     ; cl contains a 1 if the interrupt is to be hooked, and
  918.     ; edi has the interrupt number*4
  919.     cmp cl,1        ; hook it?
  920.     jnz short p1160x        ; no
  921.     push eax
  922.     mov ax,ds
  923.     mov es,ax       ; es=ds
  924.     sidt fword ptr idtlimit
  925.     add edi,idtbase
  926.     mov ax,[edi]        ; get low offset
  927.     mov word ptr [ebx],ax
  928.     mov ax,[edi+6]      ; get high offset
  929.     mov word ptr [ebx+2],ax
  930.     mov ax,[edi+2]      ; get segment 
  931.     mov word ptr [ebx+4],ax
  932.     pop eax
  933.     stosw           ; save low offset
  934.     mov ax,cs
  935.     stosw           ; save cs
  936.     mov ax,intgate      ; value for interrupt gate 
  937.     stosw           ; save misc bytes
  938.     shr eax,16
  939.     stosw           ; save high offset
  940. p1160x: ret
  941. p1160   endp
  942. VAD_Sys_Crit_Init endp
  943. ; ****************************************************************************
  944. VAD_Device_Init proc near   ; init phase 2
  945.     cmp winmsg,0        ; skip windows msg?
  946.     jz short p1200a     ; yes
  947.     mov esi,offset32 p300
  948.     VMMcall Call_When_Idle  ; setup callback
  949. p1200a:
  950.     clc         ; no error
  951.     ret
  952. VAD_Device_Init endp
  953. ; ****************************************************************************
  954. VAD_Init_Complete proc near ; init phase 3
  955.     clc         ; no error
  956.     ret
  957. VAD_Init_Complete endp
  958. VxD_Icode_Ends
  959. end
  960.